with Ada.command_line; use ada.Command_Line;
with saisir_afficher; use saisir_afficher;
with communautes_strings; use communautes_strings;
with communautes_strings_implementation_sigma; use communautes_strings_implementation_sigma;
with Ada.Unchecked_Deallocation;
with Strings;
-- with communautes_strings_implementation_optimal; use communautes_strings_implementation_optimal;

package body Serveur is
 type Acces_String is access String;
   procedure Free is new Ada.Unchecked_Deallocation (String, Acces_String);
   type Variante is (Sigma, Optimal); -- type Variante is (Sigma, Optimal);

   function Configuration return communautes_strings.communaute'Class is
   begin
      case Variante'Value (Argument (1)) is
         when Sigma => return communautes_strings_implementation_sigma.Creer;
         when Optimal => return communautes_strings_implementation_sigma.Creer;
      end case;
   exception
      when others =>
         loop
            begin
               case Variante'Value (Saisir ("sigma | optimal ? ")) is
               when Sigma => return communautes_strings_implementation_sigma.Creer;
               when Optimal => return communautes_strings_implementation_sigma.Creer;
               end case;
            exception
               when others => null;
            end;
         end loop;
   end Configuration;

   Une_communaute : communautes_Strings.communaute'Class := Configuration;
   Acces_Ici : access communautes_Strings.communaute'Class := new communautes_Strings.communaute'Class'(Une_communaute);

   protected type Individuel (Nom : access String) is
      procedure Autoriser_Consultation;
      procedure Exclure;
      entry Consulter (Nom : String; Message : in out Acces_String);
   private
      Accuse_Attendu: Boolean := False;
      Exclus : Boolean := False;
   end Individuel;

   type Acces_Individuel is access Individuel;
   procedure Free is new Ada.Unchecked_Deallocation (Individuel, Acces_Individuel);

protected Global is
   function Inscrire (N : String) return Boolean;
   function Bloquer (N, P : String) return String;
   function Debloquer (N, P : String) return String;
   function Ajouter_Cercle (N : String; C : String) return String;
   function Retirer_Cercle (N : String; C : String) return String;
   function Ajouter_Membre (N : String; C : String; P : String) return String;
   function Retirer_Membre (N : String; C : String; P : String) return String;
   function Poster (N, C, T : String) return String;
   function Commenter (N : String; I : Natural; T : String) return String;
   function Etat (N : String) return String;
   end global;

   function Inscrire (N : String) return Boolean is
      ind : Strings.Individu := strings.Individu'(new String'(N));
   begin
      if Est_inscrit(Acces_Ici.all, ind) then
         return false;
      else
         Acces_Ici := communautes_strings.Inscrire(Acces_Ici.all, ind);
         return true;
      end if;
   end Inscrire;

   function Bloquer (N, P : String) return String is
   begin
      return "";
   end Bloquer;

   function Debloquer (N, P : String) return String is
   begin
      return "";
   end Debloquer;

   function Ajouter_Cercle (N : String; C : String) return String is
   begin
      return "";
   end Ajouter_Cercle;

   function Retirer_Cercle (N : String; C : String) return String is
   begin
      return "";
   end Retirer_Cercle;

   function Ajouter_Membre (N : String; C : String; P : String) return String is
   begin
      return "";
   end Ajouter_Membre;

   function Retirer_Membre (N : String; C : String; P : String) return String is
   begin
      return "";
   end Retirer_Membre;

   function Poster (N, C, T : String) return String is
   begin
      return "";
   end Poster;

   function Commenter (N : String; I : Natural; T : String) return String is
   begin
      return "";
   end Commenter;

   function Etat (N : String) return String is
   begin
      return "";
   end Etat;

   procedure quitter is
   begin
      --services.quitter;
      null;
   end;
end Serveur;
